home *** CD-ROM | disk | FTP | other *** search
- #if TARGET_CPU_68K && !TARGET_RT_MAC_CFM
- #error Sorry Can't do that
- #endif
-
- #include <MixedMode.h>
- #include <Appearance.h>
- #include <SpeechSynthesis.h>
-
- #define kCapsLock 0x39
- #define crsrBase 0x898
- #define kTimerDelay 0x20
-
- #define kXOffset 0
- #define kYOffset 0
-
- #define kScreenXShrink 0
- #define kScreenYShrink 0
-
- typedef struct {
- short numPorts;
- GrafPtr ports [1];
- } **PortListHdl;
-
- typedef struct {
- QDGlobals qd; // Storage for the QuickDraw globals
- long qdGlobalsPtr; // A5 points to this place; it will contain a pointer to qd
- } QDStorage;
-
- typedef struct { // Time Manager information record
- TMTask tmTask; // original and revised TMtask record
- long delay;
- DeferredTask DTask;
- } TMInfo, *TMInfoPtr;
-
- void RotateScreen(void);
- void InitScreenRotate(void);
- void InitDeferedTaskStruct(DeferredTask* dtask);
- Boolean isPressed(UInt16 key, UInt8*keymap);
- void ChangeAllPorts (Ptr oldBaseAddr, Ptr newBaseAddr);
- static long MySetA5 (void* value);
- pascal void MyTask(TMInfoPtr recPtr);
- void InitTimerStruct(void);
- void MyDeferredTask(DeferredTaskProcPtr theTask);
- void CheckScreenChange(void);
-
-
- Rect gMainBounds, gOriginalBounds;
- Ptr gScreenAddress, gBufferAddress;
- short gPixelSize , gScreenRowBytes;
-
- GWorldPtr gMyGWorldPtr;
-
- QDStorage qds;
-
-
- TimerUPP gTimerProc;
- TMInfo gTask;
- Point gScreenOffset = { kYOffset, kXOffset };
- Point gScreenShrink = { kScreenYShrink, kScreenXShrink };
-
- #define kScreenRotatorGestalt 'SROT'
- #define kScreenOffsetGestalt 'SOFF'
-
- enum {
- uppA5Info = kCStackBased | RESULT_SIZE(SIZE_CODE(sizeof(long)))
- | STACK_ROUTINE_PARAMETER(1, SIZE_CODE(sizeof(long)))
- };
-
-
- // Tell MetroWerks the procInfo for main
- ProcInfoType __procinfo = kPascalStackBased;
- pascal void main(void)
- {
- RoutineDescriptorPtr originaldesc, newdesc;
- UInt32 size;
- UInt16 index;
- THz theZone;
- OSErr err;
-
- // get globals
- // EnterCodeResource();
- // detach ourselves
- DetachResource(Get1Resource('INIT', 0));
-
- // make sure we are in the system heap
- theZone = GetZone();
- SetZone(SystemZone());
-
- InitScreenRotate();
-
- gTimerProc = NewTimerProc(MyTask);
-
- InitTimerStruct();
- InitDeferedTaskStruct(&gTask.DTask);
-
- err = NewGestaltValue(kScreenRotatorGestalt, (UInt32) &gTask.delay);
- err = NewGestaltValue(kScreenOffsetGestalt, (UInt32) &gScreenOffset);
-
- InsTime((QElemPtr) &gTask.tmTask); // install the info record
- PrimeTime((QElemPtr) &gTask.tmTask, gTask.delay); // activate the info record
-
- // restore to original heap
- SetZone(theZone);
- // restore globals
- // ExitCodeResource();
- }
-
-
- void RotateScreen(void)
- {
- long height = gMainBounds.bottom - gMainBounds.top;
- long width = gMainBounds.right - gMainBounds.left;
- Ptr src_start = gBufferAddress;
- Ptr dst_start = (gScreenAddress + (height * gScreenRowBytes));
- Ptr src, dst;
- long row, col;
-
- dst_start += ((gScreenOffset.v >>1) * gScreenRowBytes);
- dst_start -= ((gScreenOffset.h >>1) * gPixelSize);
-
- for (row = 0; row < height; row++) {
- BlockMoveData(src_start, dst_start, gScreenRowBytes);
- src_start += gScreenRowBytes;
- dst_start -= gScreenRowBytes;
- }
- return;
-
- switch (gPixelSize) {
- case 8:
- for (row = 0; row < height; row++) {
- src = src_start;
- dst = dst_start;
- for (col = 0; col < width; col++) {
- *((UInt8*)dst) = *((UInt8*)src);
- dst -= sizeof(UInt8);
- src += sizeof(UInt8);
- }
- src_start += gScreenRowBytes;
- dst_start -= gScreenRowBytes;
- }
- break;
-
- case 16:
- for (row = 0; row < height; row++) {
- src = src_start;
- dst = dst_start;
- for (col = 0; col < width; col++) {
- *((UInt16*)dst) = *((UInt16*)src);
- dst -= sizeof(UInt16);
- src += sizeof(UInt16);
- }
- src_start += gScreenRowBytes;
- dst_start -= gScreenRowBytes;
- }
- break;
-
- case 24:
- for (row = 0; row < height; row++) {
- src = src_start;
- dst = dst_start;
- for (col = 0; col < width; col++) {
- *((UInt16*)dst) = *((UInt16*)src);
- dst -= sizeof(UInt16);
- src += sizeof(UInt16);
- *((UInt8*)dst) = *((UInt8*)src);
- dst -= sizeof(UInt8);
- src += sizeof(UInt8);
- }
- src_start += gScreenRowBytes;
- dst_start -= gScreenRowBytes;
- }
- break;
-
-
- case 32:
- for (row = 0; row < height; row++) {
- src = src_start;
- dst = dst_start;
- for (col = 0; col < width; col++) {
- *((UInt32*)dst) = *((UInt32*)src);
- dst -= sizeof(UInt32);
- src += sizeof(UInt32);
- }
- src_start += gScreenRowBytes;
- dst_start -= gScreenRowBytes;
- }
- break;
-
- default:
- break;
- }
- }
-
-
- void InitScreenRotate(void)
- {
- PixMapHandle dst_pixmap, main_pixmap;
- GDHandle mygdHandle, maindevice;
- THz theZone;
- CGrafPtr cwMgrPort;
- GrafPtr wMgrPort;
- Rect tempBounds = {0,0,1,1}, originalScreen;
- long bytesNeeded, oldA5;
- short wMgrRowBytes, cwMgrRowBytes;
- OSErr err;
-
- theZone = GetZone();
- SetZone(SystemZone());
-
- oldA5 = MySetA5(&qds.qdGlobalsPtr); // Tell A5 to point to the end of the fake QD Globals
- InitGraf(&qds.qd.thePort); // Initialize the fake QD Globals
-
- maindevice = LMGetMainDevice();
- main_pixmap = (**maindevice).gdPMap;
- gOriginalBounds = (**maindevice).gdRect;
- gPixelSize = (*main_pixmap)->pixelSize;
-
-
-
- gScreenRowBytes = ((**main_pixmap).rowBytes & 0x3FFF);
- gMainBounds = gOriginalBounds;
-
- originalScreen = gMainBounds;
- gMainBounds.bottom -= gScreenShrink.v;
- gMainBounds.right -= gScreenShrink.h;
- LockPixels(main_pixmap);
-
- (**maindevice).gdRect = gMainBounds;
- gScreenAddress = GetPixBaseAddr(main_pixmap);
- gMyGWorldPtr = nil;
- err = NewGWorld(&gMyGWorldPtr, (*main_pixmap)->pixelSize, &tempBounds, nil, nil, 0);
- if (err) {
- SysBeep(1);
- (**maindevice).gdRect = gOriginalBounds;
- SetZone(theZone);
- MySetA5((void*)oldA5);
- return;
- }
-
- bytesNeeded = (originalScreen.bottom - originalScreen.top) * gScreenRowBytes;
- gBufferAddress = NewPtrSysClear(bytesNeeded);
- if (!gBufferAddress) {
- SysBeep(1);
- SysBeep(1);
- (**maindevice).gdRect = gOriginalBounds;
- SetZone(theZone);
- MySetA5((void*)oldA5);
- return;
- }
-
- BlockMoveData(gScreenAddress, gBufferAddress, bytesNeeded);
-
- dst_pixmap = GetGWorldPixMap(gMyGWorldPtr);
- LockPixels (dst_pixmap);
-
- (**dst_pixmap).baseAddr = gBufferAddress;
- (**dst_pixmap).rowBytes = (**main_pixmap).rowBytes;
- (**dst_pixmap).bounds = gMainBounds;
-
- InitFonts();
- InitWindows();
- InitMenus();
- InitDialogs(nil);
-
- /* Fake out cursor drawing */
- *((Ptr*)crsrBase) = gBufferAddress;
-
- /* Fake out main GDevice */
- (**(**maindevice).gdPMap).baseAddr = gBufferAddress;
-
- GDeviceChanged (maindevice); // ••? quinn doesn't know ••
-
- /* Fake out B&W windows */
- wMgrPort = LMGetWMgrPort();
- wMgrRowBytes = wMgrPort -> portBits.rowBytes;
- wMgrPort -> portBits.baseAddr = gBufferAddress;
-
- /* Fake out color windows */
- cwMgrPort = *(CGrafPtr*)0xd2c;
- cwMgrRowBytes = (**(cwMgrPort -> portPixMap)).rowBytes;
- (**cwMgrPort -> portPixMap).baseAddr = gBufferAddress;
-
- /* Fake out QuickDraw */
- LMSetScrnBase(gBufferAddress);
-
- ChangeAllPorts (gScreenAddress, gBufferAddress);// ••? quinn doesn't know - but he's doubtful ••
- MySetA5((void*)oldA5);
- SetZone(theZone);
- }
-
- void ChangeAllPorts (Ptr oldBaseAddr, Ptr newBaseAddr)
- {
- PortListHdl ports = *((PortListHdl*) 0x0000d66);
- int i;
- for (i = 0; i < (**ports).numPorts; ++i) {
-
- if ((**ports).ports [i] -> portBits.rowBytes & 0xC000) {
-
- CGrafPtr port = (CGrafPtr) ((**ports).ports [i]);
-
- if (GetPixBaseAddr (port -> portPixMap) == oldBaseAddr)
- (**(port -> portPixMap)).baseAddr = newBaseAddr;
-
- } else {
-
- GrafPtr port = ((**ports).ports [i]);
-
- if (port -> portBits.baseAddr == oldBaseAddr)
- port -> portBits.baseAddr = newBaseAddr;
-
- }
- }
- }
-
-
- void CheckScreenChange(void)
- {
-
- Rect originalScreen;
- PixMapHandle dst_pixmap;
- GDHandle maindevice = LMGetMainDevice();
- PixMapHandle main_pixmap = (**maindevice).gdPMap;
- Rect newRect = (**maindevice).gdRect;
- short newsize = (*main_pixmap)->pixelSize;
- short newRowBytes = ((**main_pixmap).rowBytes & 0x3FFF);
-
-
- if (
- (newRect.right != gMainBounds.right || newRect.bottom != gMainBounds.bottom) ||
- (newsize != gPixelSize) ||
- newRowBytes != gScreenRowBytes) {
-
-
- gMainBounds = newRect;
- originalScreen = gMainBounds;
- gMainBounds.bottom -= gScreenShrink.v;
- gMainBounds.right -= gScreenShrink.h;
- LockPixels(main_pixmap);
-
- (**maindevice).gdRect = gMainBounds;
-
- gPixelSize = newsize;
- gScreenRowBytes = newRowBytes;
-
- dst_pixmap = GetGWorldPixMap(gMyGWorldPtr);
- LockPixels (dst_pixmap);
-
- (**dst_pixmap).baseAddr = gBufferAddress;
- (**dst_pixmap).rowBytes = (**main_pixmap).rowBytes;
- (**dst_pixmap).bounds = gMainBounds;
-
- GDeviceChanged(maindevice);
- }
- }
-
-
- //////////////////// isPressed ////////////////////
- Boolean isPressed(UInt16 key, UInt8*keymap)
- {
- return ((keymap[key>>3] >> (key & 7) ) & 1); // return true if a given key is pressed
- }
-
- static long MySetA5 (void* value)
- {
- short hex [7] = {
- 0x4e56,
- 0x0000,
- 0x202e,
- 0x0008,
- 0xc18d,
- 0x4e5e,
- 0x4e75
- };
-
- UniversalProcPtr upp;
- long oldA5;
-
- // MakeDataExecutable (&hex, 14);
-
- upp = NewRoutineDescriptor ((ProcPtr) &hex, uppA5Info, kM68kISA);
- if (!upp)
- DebugStr ("\pDONT EVEN THINK ABOUT IT!");
-
- oldA5 = CallUniversalProc (upp, uppA5Info, value);
-
- return oldA5;
- }
-
- pascal void MyTask(TMInfoPtr recPtr)
- {
- OSErr err;
- err = DTInstall(&(recPtr->DTask));
- }
-
- void InitTimerStruct(void)
- {
- gTask.tmTask.tmAddr = gTimerProc;
- gTask.tmTask.tmWakeUp = 0; // initialize tmWakeUp
- gTask.tmTask.tmReserved = 0; // initialize tmReserved
- gTask.delay = kTimerDelay;
- }
-
- void InitDeferedTaskStruct(DeferredTask* dtask)
- {
- dtask->qLink = 0;
- dtask->qType = dtQType;
- dtask->dtFlags = 0;
- dtask->dtAddr = NewDeferredTaskProc(MyDeferredTask);
- dtask->dtParam = 0;
- dtask->dtReserved = 0;
- }
-
- void MyDeferredTask(DeferredTaskProcPtr theTask)
- {
- // EnterCodeResource();
-
- if (gScreenAddress != nil && gBufferAddress != nil) {
- CheckScreenChange();
- RotateScreen();
- PrimeTime( (QElemPtr) &gTask, gTask.delay);
- }
- // ExitCodeResource();
- }
-
-
-